package com.task.common.handler;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Date;

import org.springframework.web.multipart.MultipartFile;

import com.task.common.constant.Constants;
import com.task.common.utils.date.DateUtil;
import com.task.common.utils.file.FileUtils;

import lombok.extern.slf4j.Slf4j;
import software.amazon.awssdk.core.ResponseBytes;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
import software.amazon.awssdk.services.s3.model.DeleteBucketRequest;
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import software.amazon.awssdk.services.s3.model.HeadBucketRequest;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import software.amazon.awssdk.services.s3.model.S3Exception;

@Slf4j
public class Handler {
    private final S3Client s3Client;


    public Handler() throws URISyntaxException {
        s3Client = DependencyFactory.s3Client();
    }

    public String uploadFile(MultipartFile file, String fileName) throws IOException {
        //String bucket = "bucket" + System.currentTimeMillis();
        String time = DateUtil.dateToStr(new Date(), "yyyy/MM/dd");
        String name = time + "/" + fileName;

        File convFile = null;
        try{
            convFile = FileUtils.changeToFile(file);
            //createBucket(s3Client, bucket);
            log.info("Uploading object...");

            s3Client.putObject(PutObjectRequest.builder().bucket(Constants.BUCKET)
                .key(name).build(), RequestBody.fromFile(convFile));

            //s3Client.putObject(PutObjectRequest.builder().bucket(Constants.BUCKET)
            //    .key(name).build(), RequestBody.fromBytes(file.getBytes()));
            //System.out.println(putObjectResponse);
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (convFile!=null) {
                convFile.delete();
            }
        }
        log.info("Upload complete");
        s3Client.close();
        return name;
    }

    public byte[] downloadFile(String source) {
        ResponseBytes<GetObjectResponse> responseBytes = s3Client.getObjectAsBytes(GetObjectRequest.builder()
            .bucket(Constants.BUCKET).key(source).build());
        return responseBytes.asByteArray();
    }

    public static void createBucket(S3Client s3Client, String bucketName) {
        try {
            s3Client.createBucket(CreateBucketRequest
                    .builder()
                    .bucket(bucketName)
                    .build());
            log.info("Creating bucket: " + bucketName);
            s3Client.waiter().waitUntilBucketExists(HeadBucketRequest.builder()
                    .bucket(bucketName)
                    .build());
            log.info(bucketName + " is ready.");
            System.out.printf("%n");
        } catch (S3Exception e) {
            log.error(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }

    public static void cleanUp(S3Client s3Client, String bucketName, String keyName) {
        log.info("Cleaning up...");
        try {
            log.info("Deleting object: " + keyName);
            DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder().bucket(bucketName).key(keyName).build();
            s3Client.deleteObject(deleteObjectRequest);
            log.info(keyName + " has been deleted.");
            log.info("Deleting bucket: " + bucketName);
            DeleteBucketRequest deleteBucketRequest = DeleteBucketRequest.builder().bucket(bucketName).build();
            s3Client.deleteBucket(deleteBucketRequest);
            log.info(bucketName + " has been deleted.");
            System.out.printf("%n");
        } catch (S3Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        log.info("Cleanup complete");
    }
}